package com.glkj.vipsystem.service.impl;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.glkj.vipsystem.common.enums.StockRecordType;
import com.glkj.vipsystem.common.exception.BizException;
import com.glkj.vipsystem.common.utils.Constant;
import com.glkj.vipsystem.entity.ao.*;
import com.glkj.vipsystem.entity.gen.Stock;
import com.glkj.vipsystem.entity.gen.StockRecord;
import com.glkj.vipsystem.mapper.OrderMapper;
import com.glkj.vipsystem.modules.cash.form.CashForm;
import com.glkj.vipsystem.plugin.message.MessageBuilder;
import com.glkj.vipsystem.service.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * Order 服务实现类
 * </p>
 *
 * @author Limuchan
 * @since 2019-09-11 14:56:35
 */
@Service
public class OrderService extends ServiceImpl<OrderMapper, OrderAO> implements IOrderService {
    @Resource
    private IOrderGoodsService orderGoodsService;
    @Resource
    private IVipCardRuleService vipCardRuleService;
    @Resource
    private IVipCardService vipCardService;
    @Resource
    private IStockService stockService;
    @Resource
    private IStockRecordService stockRecordService;
    @Resource
    private MessageBuilder messageBuilder;

    /**
     * 新增收银订单
     *
     * @param cashForm 收银订单信息
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void save(CashForm cashForm) {
        if (cashForm == null || CollectionUtils.isEmpty(cashForm.getGoodsList())) {
            throw new BizException("数据错误");
        }
        VipCardRuleAO rule = vipCardRuleService.selectOne(
                new EntityWrapper<VipCardRuleAO>()
                        .eq("company_id", cashForm.getCompanyId())
        );
        if (rule == null) {
            throw new BizException("公司卡规则尚未配置，不能收银");
        }
        OrderAO order = new OrderAO();
        // 计算数据
        BigDecimal orderAmount = cashForm.getOrderAmount(); // 订单金额
        BigDecimal payAmount = new BigDecimal("0"); // 现金支付金额
        BigDecimal balanceAmount = new BigDecimal("0"); // 充值卡余额抵扣金额
        BigDecimal pointsAmount = new BigDecimal("0"); // 积分抵扣金额

        int timesCost = 0; // 次数消耗
        int pointsCost = 0; // 积分消耗
        int pointsGive = 0; // 赠送积分

        VipCardAO vipCard = cashForm.getVipCard();
        Integer cardType = vipCard.getCardType();
        if (cardType == Constant.VipCardType.CHONGZHIKA.getValue()) {
            // 充值卡
            BigDecimal cardBalance = vipCard.getCardBalance();
            if (cardBalance.compareTo(orderAmount) < 0) {
                // 余额小于等于订单金额
                balanceAmount = cardBalance;
                payAmount = orderAmount.subtract(balanceAmount);
            } else {
                // 余额大于等于订单金额
                balanceAmount = orderAmount;
            }
        } else if (cardType == Constant.VipCardType.JIFENKA.getValue()) {
            // 积分卡
            // 积分能兑换的现金
            Integer cardPoints = vipCard.getCardPoints();
            BigDecimal cardPointsAmount =
                    new BigDecimal(cardPoints + "").multiply(new BigDecimal(rule.getPointsAmount()))
                            .setScale(2, BigDecimal.ROUND_DOWN);
            if (cardPointsAmount.compareTo(orderAmount) < 0) {
                pointsAmount = cardPointsAmount;
                payAmount = orderAmount.subtract(pointsAmount);
                pointsGive = Integer.parseInt(payAmount.setScale(0, BigDecimal.ROUND_DOWN).toPlainString());
            } else {
                pointsAmount = orderAmount;
            }
            // 计算积分消耗
            pointsCost = Integer.parseInt(pointsAmount.divide(new BigDecimal(rule.getPointsAmount()), 0, BigDecimal.ROUND_DOWN).toPlainString());
        } else if (cardType == Constant.VipCardType.CIKA.getValue()) {
            if (vipCard.getCardTimes() == 0 || new Date().after(vipCard.getExpireTime())) {
                throw new BizException("会员卡次数不足或会员卡已过期");
            }
            // 消耗一次
            timesCost = 1;
        } else {
            // 散客
            payAmount = orderAmount;
        }


        order.setSn(cashForm.getSn());
        order.setOrderAmount(orderAmount);
        order.setPayAmount(payAmount);
        order.setBalanceAmount(balanceAmount);
        order.setTimesCost(timesCost);
        order.setPointsCost(pointsCost);
        order.setPointsAmount(pointsAmount);
        order.setPointsGive(pointsGive);
        if (vipCard.getId() != null) {
            order.setVipCardId(vipCard.getId());
            order.setVipCardNo(vipCard.getCardNo());
            order.setMemberId(vipCard.getMemberId());
            order.setMemberName(vipCard.getMemberName());
            order.setMemberMobile(vipCard.getMemberMobile());
        }
        order.setVipCardType(cardType);
        order.setCompanyId(cashForm.getCompanyId());
        order.setCompanyName(cashForm.getCompanyName());
        order.setShopId(cashForm.getShopId());
        order.setShopName(cashForm.getShopName());
        order.setOperator(cashForm.getOperator());
        order.setCreateTime(new Date());
        order.setKaidanUserId(cashForm.getKaidanUserId());

        this.insert(order);

        Date now = new Date();

        // 保存订单项
        List<OrderGoodsAO> ogaList = new ArrayList<>();
        List<GoodsAO> goodsList = cashForm.getGoodsList();
        for (GoodsAO goodsAO : goodsList) {
            OrderGoodsAO oga = new OrderGoodsAO();
            oga.setOrderId(order.getId());
            oga.setGoodsId(goodsAO.getId());
            oga.setGoodsName(goodsAO.getGoodsName());
            oga.setGoodsUnit(goodsAO.getGoodsUnit());
            oga.setGoodsPrice(goodsAO.getGoodsPrice());
            oga.setGoodsDiscount(goodsAO.getGoodsDiscount());
            oga.setGoodsNum(goodsAO.getNum());
            oga.setCardType(goodsAO.getCardType());
            oga.setGoodsCatId(goodsAO.getCatId());
            oga.setGoodsCatName(goodsAO.getCatName());

            // 查看库存是否足够
            Stock stock = stockService.selectOne(
                    new EntityWrapper<Stock>()
                            .eq("shop_id", cashForm.getShopId())
                            .eq("goods_id", goodsAO.getId())
                            .ge("num", goodsAO.getNum())
                            .last("limit 1")
            );
            if (stock == null) {
                throw new BizException("商品[" + goodsAO.getGoodsName() + "]库存不足");
            }
            // 更新库存
            stock.setNum(stock.getNum() - goodsAO.getNum());
            stockService.updateById(stock);

            // 同时增加库存记录
            StockRecord sr = new StockRecord();
            sr.setShopId(stock.getShopId());
            sr.setDepotId(stock.getDepotId());
            sr.setGoodsId(stock.getGoodsId());
            sr.setNum(goodsAO.getNum());
            sr.setCreateTime(now);
            sr.setType(StockRecordType.XiaoShou.getType()); // 类型 销售出库
            stockRecordService.insert(sr);

            ogaList.add(oga);
        }
        orderGoodsService.insertBatch(ogaList);

        // 修改会员卡信息
        if (vipCard.getId() != null) {
            vipCardService.cost(vipCard.getId(), order.getShopId(), balanceAmount, pointsCost, pointsGive, timesCost, order.getOperator());
        }

        // 收银成功 推送消息
        if (order.getVipCardId() != null) {
            messageBuilder.buildCashMessage(order.getId());
        }
    }
}
